#include "KgGlobalData.h"
#include <QSettings>
#include <QDir>
#include "xnserial.h"
#include "cmath"
#include <QDebug>

QMutex KgGlobalData::m_mutex;
QSqlDatabase KgGlobalData::m_dataBase;

KgGlobalData::KgGlobalData(void)
{}

KgGlobalData::~KgGlobalData(void)
{}

void KgGlobalData::sqlConfig(void)
{
    QSettings set("../ini/db.ini", QSettings::IniFormat);

    QString dbDriver = "QSQLITE";
    QString dbIP = set.value("DB/IP", "127.0.0.1").toString();  
    quint16 dbPort = set.value("DB/Port", 3306).toUInt();
    QString dbDBName = set.value("DB/DBName", "../db/bams.db").toString();     
    QString dbUserName = set.value("DB/UserName", "root").toString();
    QString dbPwd = set.value("DB/Pwd", "admin").toString();  

    m_dataBase = QSqlDatabase::addDatabase(dbDriver);
	m_dataBase.setHostName(dbIP);
	m_dataBase.setPort(dbPort);
	m_dataBase.setDatabaseName(dbDBName);
	m_dataBase.setUserName(dbUserName);
	m_dataBase.setPassword(dbPwd);  
    m_dataBase.open();
}

int InnerExecDbQuery(QString strSql, QString &strError)
{  
	QSqlQuery query(KgGlobalData::m_dataBase);     
	int ret = query.exec(strSql);
	if(0 == ret)
	{
	   strError = query.lastError().text();
	}
	if (!ret) qDebug() << "EXEC:" <<strError;
	return ret;
}

int ExecDbQuery(QString strSql, QString &strError)
{
	return InnerExecDbQuery(strSql, strError);
}

void saveLogToBaDb(QString strLog)
{
	QSettings set(DEV_PATH, QSettings::IniFormat);
	if (set.value("Log/IsSaveLogToDb", 1).toInt())
	{
		QDateTime currentDt = QDateTime::currentDateTime();
		QString startDt = currentDt.toString("yyyy-MM-dd hh:mm:ss");
		QString strSql = QString("insert into tbllog(id, startDT, type, context) values(null,'%1',%2,'%3')").arg(startDt).arg(1).arg(strLog);
		QString strError;
		::ExecDbQuery(strSql,strError);
	}
}

void addToBuff(char *pData,quint16 u16Val)
{
    *pData++ = (char)(u16Val>>8);
    *pData = (char)(u16Val>>0);
}

void getFromBuff(char *pData,quint8 &u8Val)
{
    u8Val = (unsigned char)*(pData);
}

void getFromBuff(char *pData,quint16 &u16Val)
{
    quint16 temp16;
    temp16 =  (unsigned char)*(pData++);
    temp16 = temp16*256;
    temp16 += (unsigned char)*(pData);
    u16Val = temp16;
}

void getFromBuff(char *pData,quint32 &u32Val)
{
    quint32 temp32;
    temp32 =  (unsigned char)*(pData++);
    temp32 = temp32*256;
    temp32 += (unsigned char)*(pData++);
    temp32 = temp32*256;
    temp32 += (unsigned char)*(pData++);
    temp32 = temp32*256;
    temp32 += (unsigned char)*(pData);
    u32Val = temp32;
}

void getFromBuff(char *pData,quint64 &u64Val)
{
    quint64 temp64;
    temp64 =  (unsigned char)*(pData++);
    temp64 = temp64*256;
    temp64 += (unsigned char)*(pData++);
    temp64 = temp64*256;
    temp64 += (unsigned char)*(pData++);
    temp64 = temp64*256;
    temp64 += (unsigned char)*(pData++);
    temp64 = temp64*256;
    temp64 += (unsigned char)*(pData++);
    temp64 = temp64*256;
    temp64 += (unsigned char)*(pData++);
    temp64 = temp64*256;
	temp64 += (unsigned char)*(pData++);
    temp64 = temp64*256;
    temp64 += (unsigned char)*(pData);
	u64Val = temp64;
}

quint16 swapBytes(quint16 u16Val)
{
    return ((u16Val>>8)&0x00FF) | ((u16Val<<8)&0xFF00);
}

float getFloat(unsigned long data)
{
    if (data == 0) 
    {
        return 0;
    }
    ushort P1 = (ushort)(data>>16);
    ushort P2 = (ushort)data;
    int intSign, intSignRest, intExponent, intExponentRest;
    float faResult, faDigit;
    intSign = P1 / 32768;
    intSignRest = P1 % 32768;
    intExponent = intSignRest / 128;
    intExponentRest = intSignRest % 128;
    faDigit = (float)(intExponentRest * 65536 + P2) / 8388608;
    faResult = (float)pow(-1, intSign) * (float)pow(2, intExponent - 127) * (faDigit + 1);
    return faResult;
}

double getDouble(unsigned long data)
{
	double a;
	unsigned long *b = (unsigned long*)&a;
	*b = data;
	return a;
}

signed int get645Data(quint8 dataLen, char *pRecv)
{
    signed int temp32 = 0;
    quint8 a=0,b=0,c=0,d=0;
    if (pRecv[12] == 0xD1)
    {
        temp32 = 0; // 错误应答
    }
    else
    {	
		if (dataLen == 2)
		{
			getFromBuff(pRecv + 18, b);
			getFromBuff(pRecv + 19, a);
			temp32 += (((a-0x33)&0xF0)>>4)*1000;
			temp32 += (((a-0x33)&0x0F)>>0)*100;
			temp32 += (((b-0x33)&0xF0)>>4)*10;
			temp32 += (((b-0x33)&0x0F)>>0)*1;
		}
		else if (dataLen == 3)
		{
			getFromBuff(pRecv + 18, c);
			getFromBuff(pRecv + 19, b);      
			getFromBuff(pRecv + 20, a);     
			temp32 += (((a-0x33)&0x70)>>4)*100000;
			temp32 += (((a-0x33)&0x0F)>>0)*10000;
			temp32 += (((b-0x33)&0xF0)>>4)*1000;
			temp32 += (((b-0x33)&0x0F)>>0)*100;
			temp32 += (((c-0x33)&0xF0)>>4)*10;
			temp32 += (((c-0x33)&0x0F)>>0)*1;    
			if (a&0x80) temp32 = -temp32;
		}
		else if (dataLen == 4)
		{
			getFromBuff(pRecv + 18, d);
			getFromBuff(pRecv + 19, c);      
			getFromBuff(pRecv + 20, b);     
			getFromBuff(pRecv + 21, a);   
			temp32 += (((a-0x33)&0xF0)>>4)*10000000;
			temp32 += (((a-0x33)&0x0F)>>0)*1000000;
			temp32 += (((b-0x33)&0xF0)>>4)*100000;
			temp32 += (((b-0x33)&0x0F)>>0)*10000;
			temp32 += (((c-0x33)&0xF0)>>4)*1000;
			temp32 += (((c-0x33)&0x0F)>>0)*100;    
			temp32 += (((d-0x33)&0xF0)>>4)*10;
			temp32 += (((d-0x33)&0x0F)>>0)*1;    
		}
	}
    return temp32;
}

quint16 Modbus_CRC16(uchar *dat_buf,uchar dat_len)
{
	const uchar AUCHCRCHI[256] =
	{
		0x00,0x0C1,0x81,0x40,0x01,0x0C0,0x80,0x41,
		0x01,0x0C0,0x80,0x41,0x00,0x0C1,0x81,0x40,
		0x01,0x0C0,0x80,0x41,0x00,0x0C1,0x81,0x40,
		0x00,0x0C1,0x81,0x40,0x01,0x0C0,0x80,0x41,
		0x01,0x0C0,0x80,0x41,0x00,0x0C1,0x81,0x40,
		0x00,0x0C1,0x81,0x40,0x01,0x0C0,0x80,0x41,
		0x00,0x0C1,0x81,0x40,0x01,0x0C0,0x80,0x41,
		0x01,0x0C0,0x80,0x41,0x00,0x0C1,0x81,0x40,
		0x01,0x0C0,0x80,0x41,0x00,0x0C1,0x81,0x40,
		0x00,0x0C1,0x81,0x40,0x01,0x0C0,0x80,0x41,
		0x00,0x0C1,0x81,0x40,0x01,0x0C0,0x80,0x41,
		0x01,0x0C0,0x80,0x41,0x00,0x0C1,0x81,0x40,
		0x00,0x0C1,0x81,0x40,0x01,0x0C0,0x80,0x41,
		0x01,0x0C0,0x80,0x41,0x00,0x0C1,0x81,0x40,
		0x01,0x0C0,0x80,0x41,0x00,0x0C1,0x81,0x40,
		0x00,0x0C1,0x81,0x40,0x01,0x0C0,0x80,0x41,
		0x01,0x0C0,0x80,0x41,0x00,0x0C1,0x81,0x40,
		0x00,0x0C1,0x81,0x40,0x01,0x0C0,0x80,0x41,
		0x00,0x0C1,0x81,0x40,0x01,0x0C0,0x80,0x41,
		0x01,0x0C0,0x80,0x41,0x00,0x0C1,0x81,0x40,
		0x00,0x0C1,0x81,0x40,0x01,0x0C0,0x80,0x41,
		0x01,0x0C0,0x80,0x41,0x00,0x0C1,0x81,0x40,
		0x01,0x0C0,0x80,0x41,0x00,0x0C1,0x81,0x40,
		0x00,0x0C1,0x81,0x40,0x01,0x0C0,0x80,0x41,
		0x00,0x0C1,0x81,0x40,0x01,0x0C0,0x80,0x41,
		0x01,0x0C0,0x80,0x41,0x00,0x0C1,0x81,0x40,
		0x01,0x0C0,0x80,0x41,0x00,0x0C1,0x81,0x40,
		0x00,0x0C1,0x81,0x40,0x01,0x0C0,0x80,0x41,
		0x01,0x0C0,0x80,0x41,0x00,0x0C1,0x81,0x40,
		0x00,0x0C1,0x81,0x40,0x01,0x0C0,0x80,0x41,
		0x00,0x0C1,0x81,0x40,0x01,0x0C0,0x80,0x41,
		0x01,0x0C0,0x80,0x41,0x00,0x0C1,0x81,0x40
	};
	const uchar AUCHCRCLO[256] =
	{
		0,0xC0,0xC1,0x01,0xC3,0x03,0x02,0xC2,
		0xC6,0x06,0x07,0xC7,0x05,0xC5,0xC4,0x04,
		0xCC,0x0C,0x0D,0xCD,0x0F,0xCF,0xCE,0x0E,
		0x0A,0xCA,0xCB,0x0B,0xC9,0x09,0x08,0xC8,
		0xD8,0x18,0x19,0xD9,0x1B,0xDB,0xDA,0x1A,
		0x1E,0xDE,0xDF,0x1F,0xDD,0x1D,0x1C,0xDC,
		0x14,0xD4,0xD5,0x15,0xD7,0x17,0x16,0xD6,
		0xD2,0x12,0x13,0xD3,0x11,0xD1,0xD0,0x10,
		0xF0,0x30,0x31,0xF1,0x33,0xF3,0xF2,0x32,
		0x36,0xF6,0xF7,0x37,0xF5,0x35,0x34,0xF4,
		0x3C,0xFC,0xFD,0x3D,0xFF,0x3F,0x3E,0xFE,
		0xFA,0x3A,0x3B,0xFB,0x39,0xF9,0xF8,0x38,
		0x28,0xE8,0xE9,0x29,0xEB,0x2B,0x2A,0xEA,
		0xEE,0x2E,0x2F,0xEF,0x2D,0xED,0xEC,0x2C,
		0xE4,0x24,0x25,0xE5,0x27,0xE7,0xE6,0x26,
		0x22,0xE2,0xE3,0x23,0xE1,0x21,0x20,0xE0,
		0xA0,0x60,0x61,0xA1,0x63,0xA3,0xA2,0x62,
		0x66,0xA6,0xA7,0x67,0xA5,0x65,0x64,0xA4,
		0x6C,0xAC,0xAD,0x6D,0xAF,0x6F,0x6E,0xAE,
		0xAA,0x6A,0x6B,0xAB,0x69,0xA9,0xA8,0x68,
		0x78,0xB8,0xB9,0x79,0xBB,0x7B,0x7A,0xBA,
		0xBE,0x7E,0x7F,0xBF,0x7D,0xBD,0xBC,0x7C,
		0xB4,0x74,0x75,0xB5,0x77,0xB7,0xB6,0x76,
		0x72,0xB2,0xB3,0x73,0xB1,0x71,0x70,0xB0,
		0x50,0x90,0x91,0x51,0x93,0x53,0x52,0x92,
		0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,
		0x9c,0x5c,0x5d,0x9d,0x5f,0x9f,0x9e,0x5e,
		0x5a,0x9a,0x9b,0x5b,0x99,0x59,0x58,0x98,
		0x88,0x48,0x49,0x89,0x4b,0x8b,0x8a,0x4a,
		0x4e,0x8e,0x8f,0x4f,0x8d,0x4d,0x4c,0x8c,
		0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,
		0x82,0x42,0x43,0x83,0x41,0x81,0x80,0x40 
	};
	uchar j,CH,CL;
	quint16 i;
	CH = 0xFF;
	CL = 0xFF;
	for(i=0; i<dat_len; i++)
	{
		j = dat_buf[i];
		j = CH ^ j;
		CH = CL ^ AUCHCRCHI[j];
		CL = AUCHCRCLO[j];
	}
	return(CH * 0x100 + CL);
}

quint8 Em645_CRC8(uchar *dat_buf,uchar dat_len)
{
    unsigned char ucCheckSum = 0;
    for (uchar i=0; i<dat_len; i++)
    {
        ucCheckSum += *(dat_buf + i);
    }
    return ucCheckSum;
}
